<?php
namespace system\core;

/**
 * Request class
 * 
 * This class handles all the requests in the URI.
 * 
 * @author Steffen Brem <steffenbrem@gmail.com>
 * @package System.core
 */
class Request 
{
    /**
     * Stores the request string
     *  
     * @var string
     */
    private $_requestString;
    
    /**
     * Stores the Request segments
     * 
     * @var array
     */
    private $_segments = array();
    
    /**
     * Stores the Module name if there is any
     * 
     * @var string
     */
    private $_module;
    
    /**
     * Stores the current controller
     * 
     * @var string
     */
    private $_controller;
    
    /**
     * Stores the current action
     * 
     * @var string
     */
    private $_action;
    
    /**
     * Stores the current instance
     * 
     * @var System\Core\Request 
     */
    private static $_instance;
    
    /**
     * Constructor
     * 
     * Set the controller and action
     *  
     * @param string $requestUri
     */
    public function __construct() 
    {
        self::$_instance = $this;
        
        $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
        
        if ( trim($path, '/') != '' && $path != "/" )
        {
            $this->_requestString = $path;
        }
        
        // Set segments property array
        $this->_explodeSegments();
        
        $this->_checkRequestType();
       
        // Build the object (controller and action)
        $this->_build();
    }
    
    /**
     * Build the request object
     */
    private function _build()
    {        
        if ( $this->getModule() )
        {
            ( ! $this->getSegment(2) ) 
                ? $this->setController(Config::get('config', 'default_controller'))
                : $this->setController($this->getSegment(2));
            
            ( ! $this->getSegment(3) ) 
                ? $this->setAction(Config::get('config', 'default_action'))
                : $this->setAction($this->getSegment(3));
        }
        else
        {
            ( ! $this->getSegment(1) ) 
                ? $this->setController(Config::get('config', 'default_controller'))
                : $this->setController($this->getSegment(1));
            
            ( ! $this->getSegment(2) )
                ? $this->setAction(Config::get('config', 'default_action'))
                : $this->setAction($this->getSegment(2));
        }
    }


    /**
     * Get the latest Request instance
     * 
     * @return System\Core\Request
     */
    public static function getInstance()
    {
        return self::$_instance;
    }
    
    /**
     * Get the Module name
     * 
     * @return string
     */
    public function getModule()
    {
        return $this->_module;
    }
    
    /**
     * Get the controller
     * 
     * @access public
     * @return string
     */
    public function getController()
    {
        return $this->_controller;
    }
    
    /**
     * Get the action
     *  
     * @access public
     * @return string
     */
    public function getAction()
    {
        return $this->_action;
    }
    
    public function setModule( $module )
    {
        $this->_module = $module;
    }
    
    /**
     * Set the controller
     * 
     * @access public
     * @param string $controller
     */
    public function setController( $controller )
    {
        $this->_controller = $controller;
    }
    
    /**
     * Set the action method
     * 
     * @access public
     * @param string $action
     */
    public function setAction( $action )
    {
        $this->_action = $action;
    }
    
    /**
     * Get all the parameters as an array
     * 
     * @access public
     * @return array
     */
    public function getParameters()
    {
        $segments = $this->_segments;
        
        if ( $this->_module )
        {
            unset($segments[2]);
        }
        
        unset($segments[1]);
        unset($segments[0]);
            
        return array_values( array_filter($segments) );

        return array();
    }
    
    private function _explodeSegments()
    {
        foreach ( explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->_requestString) ) as $val )
        {
            $val = trim($val);

            if ($val != '')
            {
                $this->_segments[] = $val;
            }
        }
    }
    
    /**
     * Get the Request segments
     * 
     * @return array
     */
    public function getSegments()
    {
        return $this->_segments;
    }
    
    /**
     * Set request segments
     * 
     * @param array $segments
     */
    public function setSegments( array $segments )
    {
        // First clear the old segments
        $this->_segments = array();
        
        foreach ( $segments as $segment )
        {
            $this->_segments[] = $segment;
        }
        
        // Reset the properties to their new values
        $this->_build();
    }
    
    public function getSegment( $index )
    {
        $index--;
        if ( isset($this->_segments[$index]) )
        {
            return $this->_segments[$index];
        }
        return FALSE;
    }
    
    /**
     * Set a the request segment
     * 
     * @param int $index 1 = controller, 2 = action etc.
     * @param string $value
     */
    private function _setSegment( $index, $value )
    {
        if ( $this->getModule() )
        {
            ++$index;
            $this->_segments[$index] = $value;
        }
        else
        {
            $this->_segments[$index] = $value;
        }
    }
    
    /**
     * Checks for a specific request type, like a module request of localization
     * request. It also set's the needed properties for those requests!
     */
    private function _checkRequestType()
    {
        $modules = new Modules();
        
        // Is the first segment an existing module?
        if ( $modules->moduleExists($this->getSegment(1)) )
        {           
            $this->setModule( $this->getSegment(1) );
            
            // We deal with a module, so clear the old Config memory!
            Config::clearMemory();
        }
    }
}

/* End of file Request.php */